/*
 * Copyright 2022 Nightingale Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import React, { useEffect, useState, useImperativeHandle, forwardRef, useContext } from 'react';
import { Form, Row, Col, Button, Space, Switch, Tooltip, Mentions, Collapse as AntdCollapse, Select } from 'antd';
import { DeleteOutlined } from '@ant-design/icons';
import _ from 'lodash';
import { useTranslation } from 'react-i18next';
import { CommonStateContext } from '@/App';
import { Dashboard } from '@/store/dashboardInterface';
import { defaultValues, defaultCustomValuesMap } from './config';
import Options from './Options';
import Collapse, { Panel } from './Components/Collapse';
import VariableConfig, { IVariable } from '../VariableConfig';
import Renderer from '../Renderer/Renderer';
import QueryEditor from './QueryEditor';

interface IProps {
  initialValues: any;
  variableConfigWithOptions?: IVariable[];
  range: any;
  id: string;
  dashboardId: string;
  dashboard: Dashboard;
}

function FormCpt(props: IProps, ref) {
  const { t } = useTranslation('dashboard');
  const { darkMode } = useContext(CommonStateContext);
  const [chartForm] = Form.useForm();
  const { initialValues, range, id, dashboardId, dashboard } = props;
  const [variableConfigWithOptions, setVariableConfigWithOptions] = useState<IVariable[] | undefined>(props.variableConfigWithOptions);

  defaultValues.custom = defaultCustomValuesMap[initialValues?.type || defaultValues.type];

  _.forEach(initialValues.targets, (item) => {
    if (_.get(item, 'time.unit')) {
      delete item.time;
    }
  });

  useImperativeHandle(ref, () => ({
    getFormInstance: () => {
      return chartForm;
    },
  }));

  useEffect(() => {
    setVariableConfigWithOptions(props.variableConfigWithOptions);
  }, [JSON.stringify(props.variableConfigWithOptions)]);

  return (
    <Form layout='vertical' preserve={true} form={chartForm} initialValues={_.merge({}, defaultValues, initialValues)} data-oid='mgm2buc'>
      <Form.Item name='type' hidden data-oid='ovfe.oi'>
        <div data-oid='19a4igb' />
      </Form.Item>
      <Form.Item name='id' hidden data-oid='xqpy::8'>
        <div data-oid='u3.y8tq' />
      </Form.Item>
      <Form.Item name='layout' hidden data-oid='_p_-vh4'>
        <div data-oid='r:1y:pp' />
      </Form.Item>
      <Form.Item name='version' hidden data-oid='w-:lr_k'>
        <div data-oid='k92o2q2' />
      </Form.Item>
      <div
        style={{
          height: 'calc(100vh - 173px)',
        }}
        data-oid='c.xtb8w'
      >
        <Row
          gutter={20}
          style={{
            flexWrap: 'nowrap',
            height: '100%',
          }}
          data-oid='d3.2t0z'
        >
          <Col flex={1} style={{ minWidth: 100 }} data-oid='1:lajou'>
            <div style={{ marginBottom: 10, height: 300 }} data-oid='7qh0ez6'>
              <Form.Item shouldUpdate noStyle data-oid='po.ai4_'>
                {({ getFieldsValue }) => {
                  return (
                    <Renderer
                      dashboardId={dashboardId}
                      time={range}
                      values={getFieldsValue()}
                      variableConfig={variableConfigWithOptions}
                      isPreview
                      themeMode={darkMode ? 'dark' : undefined}
                      data-oid='cay11ke'
                    />
                  );
                }}
              </Form.Item>
            </div>
            <Form.Item shouldUpdate={(prevValues, curValues) => prevValues.type !== curValues.type} noStyle data-oid='s6o:wrx'>
              {({ getFieldValue }) => {
                const type = getFieldValue('type');
                if (type !== 'text' && type !== 'iframe') {
                  return (
                    <div style={{ height: 'calc(100% - 310px)', overflowY: 'auto' }} data-oid='meseq.h'>
                      <div style={{ marginBottom: 10 }} data-oid='.ler_pn'>
                        <VariableConfig
                          onChange={(value, bool, withOptions) => {
                            setVariableConfigWithOptions(withOptions || []);
                          }}
                          value={variableConfigWithOptions}
                          editable={false}
                          range={range}
                          id={dashboardId}
                          dashboard={dashboard}
                          data-oid='mryha.5'
                        />
                      </div>
                      <QueryEditor chartForm={chartForm} type={type} variableConfig={variableConfigWithOptions} dashboardId={dashboardId} time={range} data-oid='s4dyhta' />
                    </div>
                  );
                }
              }}
            </Form.Item>
          </Col>
          <Col flex='600px' style={{ overflowY: 'auto' }} data-oid='flr:cyu'>
            <Collapse data-oid='l6k7w9i'>
              <Panel header={t('panel.base.title')} data-oid='op11xqi'>
                <>
                  <Form.Item shouldUpdate={(prevValues, curValues) => prevValues.type !== curValues.type} noStyle data-oid=':ho2kko'>
                    {({ getFieldValue }) => {
                      const type = getFieldValue('type');
                      return (
                        <Form.Item
                          label={t('panel.base.name')}
                          name='name'
                          tooltip={t('panel.base.name_tip')}
                          rules={[
                            {
                              required: type === 'table',
                            },
                          ]}
                          data-oid='buzqxxt'
                        >
                          <Mentions prefix='$' split='' data-oid='lc_30ox'>
                            {_.map(variableConfigWithOptions, (item) => {
                              return (
                                <Mentions.Option key={item.name} value={item.name} data-oid='q2uqmr8'>
                                  {item.name}
                                </Mentions.Option>
                              );
                            })}
                          </Mentions>
                        </Form.Item>
                      );
                    }}
                  </Form.Item>
                  <Form.Item label={t('panel.base.link.label')} style={{ marginBottom: 0 }} data-oid='g4t4kfr'>
                    <Form.List name={'links'} data-oid='3zfovz2'>
                      {(fields, { add, remove }) => (
                        <>
                          <Button
                            style={{ width: '100%', marginBottom: 10 }}
                            onClick={() => {
                              add({});
                            }}
                            data-oid='h9uy2fe'
                          >
                            {t('panel.base.link.btn')}
                          </Button>
                          {fields.map(({ key, name, ...restField }) => {
                            return (
                              <Space
                                key={key}
                                style={{
                                  alignItems: 'flex-start',
                                }}
                                data-oid='0c3xzaa'
                              >
                                <Form.Item
                                  {...restField}
                                  name={[name, 'title']}
                                  rules={[
                                    {
                                      required: true,
                                      message: t('panel.base.link.name_msg'),
                                    },
                                  ]}
                                  data-oid='4-5qlt9'
                                >
                                  <Mentions prefix='$' split='' placeholder={t('panel.base.link.name')} data-oid='ia:chnz'>
                                    {_.map(variableConfigWithOptions, (item) => {
                                      return (
                                        <Mentions.Option key={item.name} value={item.name} data-oid=':8_0yp.'>
                                          {item.name}
                                        </Mentions.Option>
                                      );
                                    })}
                                  </Mentions>
                                </Form.Item>
                                <Form.Item
                                  {...restField}
                                  name={[name, 'url']}
                                  rules={[
                                    {
                                      required: true,
                                      message: t('panel.base.link.url_msg'),
                                    },
                                  ]}
                                  data-oid='m1wj2v8'
                                >
                                  <Mentions prefix='$' split='' style={{ width: 280 }} placeholder={t('panel.base.link.url')} data-oid='m8-3ygt'>
                                    {_.map(variableConfigWithOptions, (item) => {
                                      return (
                                        <Mentions.Option key={item.name} value={item.name} data-oid='zs-:22r'>
                                          {item.name}
                                        </Mentions.Option>
                                      );
                                    })}
                                  </Mentions>
                                </Form.Item>
                                <Tooltip title={t('panel.base.link.isNewBlank')} data-oid='z5w_1ir'>
                                  <Form.Item {...restField} name={[name, 'targetBlank']} valuePropName='checked' data-oid='5qceuaj'>
                                    <Switch data-oid='h9eo6nj' />
                                  </Form.Item>
                                </Tooltip>
                                <Button
                                  icon={<DeleteOutlined data-oid='tqaiiql' />}
                                  onClick={() => {
                                    remove(name);
                                  }}
                                  data-oid='z2ktzkc'
                                />
                              </Space>
                            );
                          })}
                        </>
                      )}
                    </Form.List>
                    <Form.Item label={t('panel.base.description')} name='description' data-oid='awgin3m'>
                      <Mentions prefix='$' split='' rows={3} data-oid='kllc8jz'>
                        {_.map(variableConfigWithOptions, (item) => {
                          return (
                            <Mentions.Option key={item.name} value={item.name} data-oid='xdi4b2f'>
                              {item.name}
                            </Mentions.Option>
                          );
                        })}
                      </Mentions>
                    </Form.Item>
                  </Form.Item>
                  <AntdCollapse ghost defaultActiveKey={[]} data-oid='zi8dimk'>
                    <AntdCollapse.Panel header={t('panel.base.repeatOptions.title')} key='1' forceRender data-oid='ttnppvj'>
                      <Row gutter={10} data-oid='zf0tz30'>
                        <Col span={12} data-oid='-1w9bgq'>
                          <Form.Item label={t('panel.base.repeatOptions.byVariable')} name='repeat' tooltip={t('panel.base.repeatOptions.byVariableTip')} data-oid='1egd2a0'>
                            <Select allowClear data-oid='bxwhp7p'>
                              {_.map(variableConfigWithOptions, (item) => {
                                return (
                                  <Select.Option key={item.name} value={item.name} data-oid='at01pws'>
                                    {item.name}
                                  </Select.Option>
                                );
                              })}
                            </Select>
                          </Form.Item>
                        </Col>
                        <Col span={12} data-oid='_61zmka'>
                          <Form.Item label={t('panel.base.repeatOptions.maxPerRow')} name='maxPerRow' initialValue={4} data-oid='271zffl'>
                            <Select allowClear data-oid='-q8w11d'>
                              {_.map([2, 3, 4, 6, 8, 12], (item) => {
                                return (
                                  <Select.Option key={item} value={item} data-oid='j8q_gxz'>
                                    {item}
                                  </Select.Option>
                                );
                              })}
                            </Select>
                          </Form.Item>
                        </Col>
                      </Row>
                    </AntdCollapse.Panel>
                  </AntdCollapse>
                </>
              </Panel>
              <Form.Item shouldUpdate={(prevValues, curValues) => !_.isEqual(prevValues.targets, curValues.targets)} data-oid='aabtnx2'>
                {({ getFieldValue }) => {
                  return (
                    <Options
                      type={getFieldValue('type')}
                      targets={getFieldValue('targets')}
                      chartForm={chartForm}
                      variableConfigWithOptions={variableConfigWithOptions}
                      data-oid='19fdchb'
                    />
                  );
                }}
              </Form.Item>
            </Collapse>
          </Col>
        </Row>
      </div>
    </Form>
  );
}

export default forwardRef(FormCpt);
